import { NextFunction, Request, Response, Router } from "express";
import { Block } from "../../model/block";
import { BaseController } from "../BaseController";
import { MongoDB } from "../DB/MongoDB";
import { Utils } from "../../utils";
import { isNumber } from "util";
//const tagg = require('tagg2');//异步模块


export class BuilderController extends BaseController {


    public blockChain: Array<any> = [];

    private mongoDB: any;

    /**
     * Constructor
     *
     * @class BuilderController
     * @constructor
     */
    constructor() {
        super();
        this.mongoDB = new MongoDB("block");
    }

    /**
     * 创建创世链
     * @param req 
     * @param res 
     * @param next 
     */
    public createGenesisBlock() {
        let data =  "by:欧阳杰-创世链";
        let block_data = new Block(0, Utils.getTimeStamp(), data, Utils.getRandom(), "");
        return block_data;
    }


    /**
     * 生成下级区块 算力证明
     * @param lastBlock  最后一级区块
     */
    public LastBlock(lastBlock: Block) {
        try {
            let random_str =Utils.getRandom();
            let index = lastBlock["index"] + 1; 
            let timestamp = Utils.getTimeStamp();
            let data = { name: "李四", sex: "男" };
            let block: Block = new Block(index, timestamp, data, random_str, lastBlock["hash"]);
            //前十位不是数字   
            let number: string = block.getHash().substring(0, 4);
            var reg = /^[1-9]+[0-9]*]*$/; //判断字符串是否为数字 //判断正整数   
            if (!reg.test(number)) {
                return false;
            }
            return block;
        } catch (error) {
            return "区块链生成错误";
        }

    }


    public asyncCreateBlock() {
        // console.time('8 thread');
        // var numThreads = 8; //创建线程池，最大数为8
        // var thread = tagg.create(this.LastBlock,function(err, res){
        //     if(err) throw new(err);//如果在线程中throw异常，err就会得到相应的错误
        //     console.log(res);//fibo(40)的结果
        //     thread.destroy();//摧毁线程
        // });
        // var threadPool = tagg.createPool(numThreads).all.eval(this.LastBlock); //为线程池注册程序
        // var i = 8;
        // var cb = function (err, data) { //注册线程执行完毕的回调函数
        //     console.log(data);
        //     if (!--i) {
        //         threadPool.destroy();
        //         console.timeEnd('8 thread');
        //     }
        // }

        // let firstBlock = this.createGenesisBlock();
        // this.blockChain[0] = firstBlock;
        // let previousBlock = this.blockChain[0];

        // threadPool.any.eval('this.LastBlock("'+firstBlock+'")', cb);   
        // threadPool.any.eval('this.LastBlock("'+firstBlock+'")', cb);  
        // threadPool.any.eval('this.LastBlock("'+firstBlock+'")', cb);   
        // threadPool.any.eval('this.LastBlock("'+firstBlock+'")', cb);   
        // threadPool.any.eval('this.LastBlock("'+firstBlock+'")', cb);  
        // threadPool.any.eval('this.LastBlock("'+firstBlock+'")', cb);  
        // threadPool.any.eval('this.LastBlock("'+firstBlock+'")', cb);  
        // threadPool.any.eval('this.LastBlock("'+firstBlock+'")', cb);  

    }


    public getLastBlock(req: Request, res: Response, next: NextFunction) { 
        this.mongoDB.select({}, { timeStamp: -1 }, -1).then((data) => {
            res.json(this.ResultMsg(data));
        }).catch((error) => {
            res.json(error);
        }); 
        // this.mongoDB.select({}).then((data) => { 
        //     res.json(this.ResultMsg(data));
        // }).catch((error) => {
        //     res.json(error); 
        // });
    }

    /**
     * 创建区块链
     */
    public createBlock(req: Request, res: Response, next: NextFunction) {
        // next();
        // this.mongoDB.delete({}).then((data) => {
        //     console.log(data);
        // }).catch((error) => {
        //     console.log(error);
        // }); 
        let $this = this;
        this.mongoDB.select({}, { timeStamp: -1 }, -1).then((data) => {
            let firstBlock;
            if (data.length > 0) {
                firstBlock = data[0];
            } else {
                firstBlock = $this.createGenesisBlock();
            } 
            let previousBlock = firstBlock;
            console.time('8 thread');
            while (true) {
                let newBlock = $this.LastBlock(previousBlock);
                if (!newBlock) {
                    continue;
                }
                else if (typeof(newBlock) == "string") {
                    res.json($this.ResultMsg(newBlock));
                    break;
                }
                else {
                    $this.mongoDB.insertOne(newBlock).then((data) => {
                        next();
                    }).catch((error) => {
                        console.error(error);
                        res.json($this.ResultMsg(error));
                    });
                    break;
                }
            }
            console.timeEnd('8 thread');
        }).catch((error) => {
            console.error("搜索异常");
            console.error(error);
            res.json($this.ResultMsg(error));
        });

        //   return this.ResultMsg(this.blockChain);
    }

    /** 
     * 验证区块 
     * 这也是一个复杂的过程，为了简单，我们这里直接返回正确 
     * @param array $data 
     */
    public verify() {
        return true;
    }


}